package com.sanerzone.smscenter.config.impl;

import com.alibaba.druid.support.json.JSONUtils;
import com.google.common.collect.Maps;
import com.sanerzone.common.support.sequence.MsgId;
import com.sanerzone.smscenter.biz.DataAccessCachImpl.DataAccessCachImpl;
import com.sanerzone.smscenter.biz.VerifyInterface.GatewayVerify;
import com.sanerzone.smscenter.biz.VerifyInterface.data.ResultData;
import com.sanerzone.smscenter.biz.VerifyInterface.data.Sort;
import com.sanerzone.smscenter.biz.VerifyInterface.impl.GatewayVerifyImpl;
import com.sanerzone.smscenter.biz.VerifyInterface.util.FilterUtil;
import com.sanerzone.smscenter.biz.VerifyInterface.util.MatchUtil;
import com.sanerzone.smscenter.biz.cache.AccountCacheHelper;
import com.sanerzone.smscenter.biz.cache.GatewayCacheHelper;
import com.sanerzone.smscenter.biz.entity.SmsGateway;
import com.sanerzone.smscenter.biz.entity.SmsSend;
import com.sanerzone.smscenter.biz.entity.SmsSendVo;
import com.sanerzone.smscenter.biz.iface.DataAccess.DataAccess;
import com.sanerzone.smscenter.biz.iface.WebServiceInterface;
import com.sanerzone.smscenter.biz.mapper.SmsSendMapper;
import com.sanerzone.smscenter.biz.message.SMSMTMessage;
import com.sanerzone.smscenter.biz.message.SMSREQMessage;
import com.sanerzone.smscenter.biz.message.SMSURREQMessage;
import com.sanerzone.smscenter.biz.utils.DateHelper;
import com.sanerzone.smscenter.biz.utils.SignHelper;
import com.sanerzone.smscenter.biz.utils.StringHelper;
import com.sanerzone.smscenter.biz.utils.TableNameHelper;
import com.sanerzone.smscenter.common.tools.JedisUtils;
import com.sanerzone.smscenter.common.tools.MQHelper;
import com.sanerzone.smscenter.common.tools.SpringContextHelper;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class WebServiceInterfaceImpl implements WebServiceInterface{
    @Autowired
    public MQHelper mQUtils;

    public static Logger logger = LoggerFactory.getLogger(WebServiceInterfaceImpl.class);

    private static GatewayVerify gatewayVerify=new GatewayVerifyImpl();
    private static DataAccess dataAccess=new DataAccessCachImpl();
    @Autowired
    private SmsSendMapper smsSendMapper;

    public boolean setFalseSendMt(SmsSendVo smsSend){
        //封装一个req
        SMSREQMessage message = new SMSREQMessage();
//        String taskId = new MsgId( 1000001 ).toString();

        message.setTaskid( smsSend.getTaskid() );
        message.setCustomServiceid( smsSend.getCustomServiceid() );
        message.setAccId( smsSend.getAccId() );
        message.setUserid( smsSend.getUserid() );
        message.setFeeType( AccountCacheHelper.getStringValue( smsSend.getUserid() + "_0", "feeType", "1" ) );
        message.setFeePayment( "1" );//默认值
        message.setCustomTaskid( smsSend.getCustomTaskid() );
        message.setCustomServiceid( "0" );
        message.setPhones( smsSend.getPhone() );
        message.setMsgContent( smsSend.getSmsContent() );
        message.setSmsContentId( smsSend.getSmsContentId() );
        message.setSmsType( "0" );//短信
        message.setSourceGateWayId( "HTTP" );
        message.setSourceGateWayProto( "HTTP" );
        message.setMassFlag( "0" );//单个发送
        message.setSendTime( new Date() );
        message.setReceiveTime( smsSend.getReceiveTime() );
        message.setParamValue( smsSend.getParamValue() );
        message.setRegisteredDelivery(
                StringHelper.registeredDelivery( AccountCacheHelper.getStringValue( smsSend.getUserid() + "_" + smsSend.getAccId(), "callbackUrl", "" ) ) ? "1" : "0" );
        message.setDeliveryGateWayId( "HTTP" );
        message.setTaskid( smsSend.getTaskid() );
        SMSMTMessage entity;

        String content = message.getMsgContent();//短信内容
        String code = "F000"; //最开始设置成提交成功
        String templateId = message.getSmsContentId();//得到模板Id
        String phone = message.getPhones();
        entity = new SMSMTMessage();
        entity.setId( new MsgId().toString() );
        entity.setSmsREQMessage( message );
        entity.getSmsREQMessage().setPhones( "" );//把req的phones设置成空串
        entity.setContentType( "0" );//内容类型 默认 0   0是什么意思？
        entity.setSmsContent( content );//短信内容
        entity.setPhoneType( smsSend.getPhoneType() );
        entity.setPhoneArea( smsSend.getPhoneArea() );
        entity.setPhone( phone );
        entity.setSmsContentSign( getSign( content ) );//短信签名
        entity.setServiceId( message.getCustomServiceid()); //默认业务
        entity.setFailReason( "后台审核不通过" );
        entity.setSendStatus( code );
        entity.setBizTime( new Date() );
        entity.setSmsSize( smsSend.getSmsSize() );
        entity.setIsEffective( 1 );
        entity.setShowLevel( 2 );
        entity.setNeedSplit( 1 );

        String msgId=mQUtils.sendSmsMT( entity.getId(), entity );
        if (msgId!=null){
            return true;
        }else{
            return false;

        }

    }



    public boolean doCheck(SmsSendVo smsSend){
        //封装一个req
        SMSREQMessage message = new SMSREQMessage();
//        String taskId = new MsgId( 1000001 ).toString();

        message.setTaskid( smsSend.getTaskid() );
        message.setAccId( smsSend.getAccId() );
        message.setUserid( smsSend.getUserid() );
        message.setFeeType( AccountCacheHelper.getStringValue( smsSend.getUserid() + "_0", "feeType", "1" ) );
        message.setFeePayment( "1" );//默认值
        message.setCustomTaskid( smsSend.getCustomTaskid() );
        message.setCustomServiceid( smsSend.getCustomServiceid() );
        message.setPhones( smsSend.getPhone() );
        message.setMsgContent( smsSend.getSmsContent() );
        message.setSmsContentId( smsSend.getSmsContentId() );
        message.setSmsType( "0" );//短信
        message.setSourceGateWayId( "HTTP" );
        message.setSourceGateWayProto( "HTTP" );
        message.setMassFlag( "0" );//单个发送
        message.setSendTime( new Date() );
        message.setReceiveTime( smsSend.getReceiveTime());
        message.setParamValue( smsSend.getParamValue() );
        message.setRegisteredDelivery(
                StringHelper.registeredDelivery( AccountCacheHelper.getStringValue( smsSend.getUserid() + "_" + smsSend.getAccId(), "callbackUrl", "" ) ) ? "1" : "0" );
        message.setDeliveryGateWayId( "HTTP" );
        message.setSubmitId( smsSend.getSubmitId() );
        //        message.setInsertOrUpdate( 2 );//更新
        //拿到短信状态 不是敏感字的原因，
        String status = smsSend.getSendStatus();
        if (!status.equals( "V003" )) {
            String msgid = mQUtils.sendSmsREQ( "SINGLE", smsSend.getTaskid(), message );
            if ("-1".equals( msgid )) {
                return false;
            }else{
                return true;
            }

        } else {
            SMSMTMessage entity;
            String userid = message.getUserid();
            String accId = message.getAccId();

            String key = userid + "_" + accId;
            String content = message.getMsgContent();//短信内容
            String code = "T000"; //最开始设置成提交成功
            String templateId = message.getSmsContentId();//得到模板Id
            String phone = message.getPhones();
            entity = new SMSMTMessage();
            entity.setId( smsSend.getId() );
            entity.setSmsREQMessage( message );
            entity.getSmsREQMessage().setPhones( "" );//把req的phones设置成空串
            entity.setContentType( "0" );//内容类型 默认 0   0是什么意思？
            entity.setSmsContent( content );//短信内容
            entity.setPhoneType( smsSend.getPhoneType() );
            entity.setPhoneArea( smsSend.getPhoneArea() );
            entity.setPhone( phone );
            entity.setSmsContentSign( getSign( content ) );//短信签名
            entity.setServiceId( message.getCustomServiceid() ); //默认业务

            FilterUtil.setSplit( phone, entity );
            //			code = getPhoneOpt( entity );//获取号码属性
            //获得应是短信类型 1 2 3 验证码，通知，营销
            String accountGroupId = AccountCacheHelper.getStringValue( key, "groupId", "" );
            //SmsGateway smsGateway = null;//最终要找的网关

            List<SMSMTMessage> result = new ArrayList<>();
            //是签名的原因
            ResultData resultData = null;
            resultData = gatewayVerify.filterBlackList( phone, accountGroupId, message,dataAccess );
            //将不合法订单也放入结果集中
            if (resultData.getSmsmtMessage() != null) {
                result.add( resultData.getSmsmtMessage() );
                phone = resultData.getPhoneStringAfterFilter();
                entity.setPhone( phone );
            }
            //限制该用户不能发送的运营商号码
            if ("T000".equals( resultData.getCode() )) {
                resultData = gatewayVerify.filterUserNotAllowedOprator( key, phone, message ,dataAccess
                );
                if (resultData.getSmsmtMessages().size() > 0) {
                    //循环添加每一个衍生出来的订单
                    for (SMSMTMessage smsmtMessage : resultData.getSmsmtMessages()) {
                        result.add( smsmtMessage );
                    }
                    phone = resultData.getPhoneStringAfterFilter();
                    if (phone.equals( "" )){
                        for (SMSMTMessage temp : result) {
                            mQUtils.sendSmsMT( entity.getId(), temp );
                        }
                        return true;

                    }
                    entity.setPhone( phone );

                }
                if (!(phone.equals( "" ))&&"T000".equals( resultData.getCode() )) {
                    //最后找网关  真正找网关因为是分找到的多个网关，所以不返回，内部处理
                    resultData = gatewayVerify.gateWayMatching( templateId, accountGroupId, entity, phone, message, result,dataAccess );

                    if (resultData.getCode() != null && resultData.getCode().startsWith( "V" )) {
                        code = resultData.getCode();
                    } else {
                        List<SMSMTMessage> list = resultData.getResult();
                        for (SMSMTMessage temp : list) {
                            mQUtils.sendSmsMT( entity.getId(), temp );
                        }
                        return true;
                    }

                } else {
                    code = resultData.getCode();
                }
            }
            entity.setCheckReason( resultData.getCheckReason() );
            entity.setFailReason( resultData.getFailReason() );
            entity.setWaitReason( resultData.getWaitReason() );
            entity.setSendStatus( code );
            entity.setBizTime( new Date() );
            entity.setUpdateOrInsert( message.getInsertOrUpdate() );//获取到是更新还是插入
            entity.setSmsSize( ( phone.split( "," ).length ) * smsSize( content ) );//短信长度
            FilterUtil.setNeedSplit( entity );
            entity.setIsEffective( 1 );
            if (phone.length() != 0) {
                result.add( entity );
            }
            for (SMSMTMessage smsmtMessage : result) {
                mQUtils.sendSmsMT( entity.getId(), smsmtMessage );
            }
            return true;
        }


    }

    @Override
    public boolean checkOrder(SmsSendVo smsSend) {

        boolean result=doCheck( smsSend );
        if (result){
            setOrderLoseEfficacy(smsSend);
        }
        return result;

    }

    public void setOrderLoseEfficacy(SmsSendVo smsSend){
        SqlSession sqlSession=null;
        try {
            //要把这条订单设置失效
            sqlSession = SpringContextHelper.getBean(SqlSessionFactory.class).openSession();
            //修改短信发送状态
            Map<String,Object> map = Maps.newHashMap();
            map.put("id",smsSend.getId());
            map.put("tableName", TableNameHelper.getSmsSendTable(smsSend.getId()));
            sqlSession.insert("com.sanerzone.smscenter.biz.mapper.SmsSendMapper.setOrderDisable", map);
            sqlSession.commit();
        }catch (Exception e){
            logger.error( "设置订单失效失败" );
        }finally {
            if (sqlSession!=null){
                sqlSession.close();
            }
        }

    }


    @Override
    public boolean waitSended(SmsSendVo smsSend, String groupId,String gatewayCode) {

        boolean flag=doSended( smsSend,groupId,gatewayCode );

        if (flag&&smsSend.getShowLevel().equals( "2" )){
            setOrderLoseEfficacy( smsSend );
        }

        return flag;
    }

    public boolean doSended(SmsSendVo smsSend, String groupId,String gatewayCode){
        //封装一个req
        SMSREQMessage message = new SMSREQMessage();
//        String taskId = new MsgId( 1000001 ).toString();

        message.setTaskid( smsSend.getTaskid() );
        message.setAccId( smsSend.getAccId() );
        message.setUserid( smsSend.getUserid() );
        message.setFeeType( AccountCacheHelper.getStringValue( smsSend.getUserid() + "_0", "feeType", "1" ) );
        message.setFeePayment( "1" );//默认值
        message.setCustomTaskid( smsSend.getCustomTaskid() );
        message.setCustomServiceid( smsSend.getCustomServiceid() );
        message.setPhones( smsSend.getPhone() );
        message.setMsgContent( smsSend.getSmsContent() );
        message.setSmsContentId( smsSend.getSmsContentId() );
        message.setSmsType( "0" );//短信
        message.setSourceGateWayId( "HTTP" );
        message.setSourceGateWayProto( "HTTP" );
        message.setMassFlag( "0" );//单个发送
        message.setSendTime( new Date() );
        message.setReceiveTime( smsSend.getReceiveTime() );
        message.setParamValue( smsSend.getParamValue() );
        message.setRegisteredDelivery(
                StringHelper.registeredDelivery( AccountCacheHelper.getStringValue( smsSend.getUserid() + "_" + smsSend.getAccId(), "callbackUrl", "" ) ) ? "1" : "0" );
        message.setDeliveryGateWayId( "HTTP" );
        message.setSubmitId( smsSend.getSubmitId() );
        int showLevel=Integer.parseInt( smsSend.getShowLevel());
        if (showLevel==1){//单条设置为不做数据库操作  标志位3
            message.setInsertOrUpdate(3  );
        }else{
            message.setInsertOrUpdate( 1 );
        }

        //封装MT
        SMSMTMessage entity;
        String userid = message.getUserid();
        String accId = message.getAccId();

        String key = userid + "_" + accId;
        String content = message.getMsgContent();//短信内容
        String code = "T000"; //最开始设置成提交成功
        String templateId = message.getSmsContentId();//得到模板Id
        String phone = message.getPhones();
        entity = new SMSMTMessage();
        entity.setSmsREQMessage( message );
        entity.getSmsREQMessage().setPhones( "" );//把req的phones设置成空串
        entity.setContentType( "0" );//内容类型 默认 0   0是什么意思？
        entity.setSmsContent( content );//短信内容
        entity.setPhoneType( smsSend.getPhoneType() );
        entity.setPhoneArea( smsSend.getPhoneArea() );
        entity.setPhone( phone );
        entity.setSmsContentSign( getSign( content ) );//短信签名
        entity.setServiceId( message.getCustomServiceid() ); //默认业务
        entity.setSendStatus( code );
        entity.setSmsSize( ( phone.split( "," ).length ) * smsSize( content ) );//短信长度
        FilterUtil.setSplit( phone, entity );
        entity.setId( new MsgId( ).toString() );
        entity.setIsEffective( 1 );
        entity.setMtBatchNum( smsSend.getMtBatch() );

        //			code = getPhoneOpt( entity );//获取号码属性
        //获得应是短信类型 1 2 3 验证码，通知，营销
        String accountGroupId = AccountCacheHelper.getStringValue( key, "groupId", "" );
        //SmsGateway smsGateway = null;//最终要找的网关

        List<SMSMTMessage> result = new ArrayList<>();
        ResultData resultData=null;
        //选择groupid重发
        if (StringUtils.isNotBlank( groupId )){
            entity.setGatewayGroup( groupId );
            resultData=gatewayVerify.gateWayMatching( templateId,groupId,entity,phone,message,result,dataAccess );
            if (resultData.getCode()!=null&&resultData.getCode().startsWith( "V" )){
                //进入待审核
                code=resultData.getCode();
                entity.setCheckReason( resultData.getCheckReason() );
                entity.setFailReason( resultData.getFailReason() );
                entity.setWaitReason( resultData.getWaitReason() );
                entity.setSendStatus( code );
                entity.setBizTime( new Date() );
                entity.setNeedSplit( 0 );
                entity.setUpdateOrInsert( message.getInsertOrUpdate() );//获取到是更新还是插入

                FilterUtil.setNeedSplit( entity );

                if (phone.length() != 0) {
                    result.add( entity );
                }
                boolean resultFlag=true;
                for (SMSMTMessage smsmtMessage : result) {
                   String msgId= mQUtils.sendSmsMT( entity.getId(), smsmtMessage );
                   if (msgId==null){
                       resultFlag=false;
                   }
                }
                return resultFlag;
            }else{
                for (SMSMTMessage smsmtMessage1:result){
                    int updateOrInsert=smsmtMessage1.getSmsREQMessage().getInsertOrUpdate();
                    smsmtMessage1.setUpdateOrInsert( updateOrInsert );

                }
                return  sendResultToMT( result );
            }

        }else {
            //选择gatewayid重发
            List<Sort> sorts = new ArrayList<>();
            Sort sort = new Sort();
            sort.setSb( new StringBuffer( smsSend.getPhone() ) );
            SmsGateway smsGateway = GatewayCacheHelper.get( gatewayCode );
            sort.setSmsGateway( smsGateway );
            sort.setGroupId( groupId );
            sorts.add( sort );
            //直接下发
             MatchUtil.sendInBatches( sorts, result, message, null );
            for (SMSMTMessage smsmtMessage:result){
                int updateOrInsert=smsmtMessage.getSmsREQMessage().getInsertOrUpdate();
                smsmtMessage.setUpdateOrInsert( updateOrInsert );
                smsmtMessage.setMtBatchNum( smsSend.getMtBatch() );

            }
           return  sendResultToMT( result );
        }


    }

    @Override
    public boolean trySendedByGWcode(SmsSendVo smsSend, String gatewayCode) {
        List<SMSMTMessage> result=new ArrayList<>( );
        SMSREQMessage message = new SMSREQMessage();
        message.setTaskid(new MsgId(1000001).toString() );
        message.setAccId( smsSend.getAccId() );
        message.setUserid( smsSend.getUserid() );
        message.setPhones( smsSend.getPhone() );
        message.setMsgContent( smsSend.getSmsContent() );
        message.setGatewayId( gatewayCode );
        message.setGatewayGroup( smsSend.getGatewayGroup() );
        message.setFeeType( smsSend.getFeeType() );
        message.setSendTime( new Date(  ) );
        List<Sort> sorts = new ArrayList<>();
        Sort sort = new Sort();
        sort.setSb( new StringBuffer( smsSend.getPhone() ) );
        SmsGateway smsGateway = GatewayCacheHelper.get( gatewayCode );
        if (smsGateway==null||"0".equals(smsGateway.getGwStatus())){
            return false;
        }
        sort.setSmsGateway( smsGateway );
        sorts.add( sort );
        //直接下发
        MatchUtil.sendInBatches( sorts, result, message, null );
        return  sendResultToMT( result );
    }






    public boolean sendResultToMT(List<SMSMTMessage> result){
        for (SMSMTMessage mtMsg : result)
        {
            mtMsg.setMtBatchNum( new MsgId(1000001).toString() );
            String msgid = mQUtils.sendSmsMT(mtMsg.getId(), mtMsg);

            if (msgid == null)
            {
                logger.error("网关：{}, body:{}",mtMsg.getGatewayId(), JSONUtils.toJSONString(mtMsg));
                return false;
            }
        }
        return true;
    }



    //获取签名
    private static String getSign(String content){
        return SignHelper.get(content);
    }
    public static int smsSize(String smsContent){
        return StringHelper.smsSize(smsContent);
    }

    @Override
    public boolean setSucOrFalse(String ids, String sendStatus) {
        SqlSession sqlSession=null;
        try {
            sqlSession = SpringContextHelper.getBean(SqlSessionFactory.class).openSession();
            int count=0;
            String[] idsArray=ids.split( ";" );
            for (int i=0;i<idsArray.length;i++){
                String id=idsArray[i];
                Map map=new HashMap( );
                map.put( "tableName",TableNameHelper.getSmsSendTable( id ) );
                if (sendStatus.startsWith( "T" )){
                    map.put( "gatewayStatus","T100" );
                }else if (sendStatus.startsWith( "F" )){
                    map.put( "gatewayStatus","F10102" );
                }
                map.put( "sendStatus","T000" );
                map.put( "id",id );
                int update = sqlSession.update("com.sanerzone.smscenter.biz.mapper.SmsSendMapper.updateStatusById", map);

                if (update>0){
                    Map map1=new HashMap( );
                    map1.put( "id",id );
                    map1.put( "tableName",TableNameHelper.getSmsSendTable( id ) );
                    SmsSend smsSend=smsSendMapper.getById( map1 );
                    count++;
                    //反充值这条
                    if (sendStatus.startsWith( "F" )){
                        //如果失败   F
                        String amountKey=AccountCacheHelper.getAmountKey("sms", smsSend.getUserid());
                        JedisUtils.incrBy( amountKey, smsSend.getSmsSize());
                        logger.info( "用户id:{},反充结束,反充条数为{}",smsSend.getUserid(),smsSend.getSmsSize() );

                    }


                    //将这条失败 或者成功推送给用户
                    SMSURREQMessage sMSURREQMessage = new SMSURREQMessage();
                    sMSURREQMessage.setAccid( smsSend.getAccId() );
                    sMSURREQMessage.setBizid( smsSend.getId() );
                    sMSURREQMessage.setDoneTime( DateHelper.formatCmppDate( smsSend.getSubmitTime() ) );
                    sMSURREQMessage.setGateWayId( smsSend.getGatewayId() );
                    sMSURREQMessage.setMsgid( smsSend.getMtBatch() );
                    sMSURREQMessage.setPhone( smsSend.getPhone() );
                    sMSURREQMessage.setSourceGateWayId( smsSend.getSourceGatewayId() );
                    sMSURREQMessage.setSpnumber( smsSend.getSpnumber());
                    sMSURREQMessage.setStat( sendStatus );
                    sMSURREQMessage.setSubmitTime( DateHelper.formatCmppDate( smsSend.getSubmitTime() ));
                    sMSURREQMessage.setTaskid(smsSend.getTaskid());
                    sMSURREQMessage.setUserid( smsSend.getUserid() );
                    sMSURREQMessage.setMessageid( smsSend.getCustomServiceid() );
                    sMSURREQMessage.setReserve( "人工操作" );
                    mQUtils.sendSmsUR( smsSend.getId(), sMSURREQMessage );
                }
                if (count%500==0){
                    sqlSession.commit();
                }
            }










        }catch (Exception e){
            e.printStackTrace();
            return false;
        }finally {
            if (sqlSession!=null){
                sqlSession.close();
            }
        }





        return true;
    }
}
